#coding:utf-8

import Config;
import wx;
import os;
import wx.lib.rcsizer as rcs;
import wx.lib.intctrl;
import Global;
import Loading;
import string;
import ELog;
import traceback;
import array;
import time;
import numpy;  
import matplotlib;
import matplotlib.figure;
import matplotlib.backends.backend_wxagg;
import matplotlib.backends.backend_wx;

try:
    from agw import fourwaysplitter as FWS
except ImportError: # if it's not there locally, try the wxPython lib.
    try:
        import wx.lib.agw.fourwaysplitter as FWS
    except ImportError:
        exit()

#菜单ID
from AppIds import *

import SerialUtil
import wx.lib.newevent

#Frame start
SERIAL_GENIUS_FS_CHAR=0x0F;
#Slash
SERIAL_GENIUS_SL_CHAR=0x1F;


#发送数据模块
class Send(wx.Panel):

    def __init__(self, parent):

        wx.Panel.__init__(self, parent, style=wx.BORDER_DOUBLE);
        
        ############# 状态信息 ############
        #该模块是否启用
        self.isUsing=False;

        ############# 配置信息 ############
        self.hexMode=False;
        self.sendNewLineMode=False;
        self.sendTimelyMode=False;
        self.sendTimelyInterval=0;
        self.dataBuffer=[];
        self.dataHexBuffer=[];
        self.sendTimer = wx.Timer(self);
        self.Bind(wx.EVT_TIMER, self.OnSendDataTimer);

        ############# 开始布局 ###########
        gridSizer = rcs.RowColSizer();

        rowTotal=5;
        colTotal=3;

        #标题
        title=wx.StaticText(self, -1, u"发送");
        title.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD ));
        gridSizer.Add(title, pos=(0,0), size=(1, colTotal), flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL);
        
        #数据
        self.textSendData = wx.TextCtrl(self, style=wx.TE_MULTILINE);
        self.textSendData.SetFont(wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL ));
        gridSizer.Add(self.textSendData, pos=(1,0), size=(1, colTotal), flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL);
        self.textSendData.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus);
        

        #十六进制
        self.checkboxHexMode=wx.CheckBox(self, -1, u"十六进制格式");
        self.checkboxHexMode.Bind(wx.EVT_CHECKBOX, self.OnHexMode);
        gridSizer.Add(self.checkboxHexMode, pos=(2, 0), size=(1,colTotal), flag=wx.ALIGN_CENTER_VERTICAL);
        if Config.APP_CONFIG['module_send']['hexMode']=='1':
            self.checkboxHexMode.SetValue(True);
            self.hexMode=True;
                
        #发送新行
        self.checkboxNewLine=wx.CheckBox(self, -1, u"发送新行");
        self.checkboxNewLine.Bind(wx.EVT_CHECKBOX, self.OnSendNewLineMode);
        gridSizer.Add(self.checkboxNewLine, pos=(2, 1), size=(1,1), flag=wx.ALIGN_CENTER_VERTICAL);
        if Config.APP_CONFIG['module_send']['sendNewLine']=='1':
            self.checkboxNewLine.SetValue(True);
            self.sendTimelyMode=True;
        if self.hexMode:
            self.checkboxNewLine.Enable(False);
        else:
            self.checkboxNewLine.Enable(True);
        
        #选择发送文件
        self.btnSelectFile = wx.Button(self, -1, u"选择文件");
        self.btnSelectFile.Bind(wx.EVT_BUTTON, self.OnSelectFile);
        gridSizer.Add(self.btnSelectFile, pos=(2, 2), size=(1,1), flag=wx.ALIGN_CENTER_VERTICAL);
        
        #定时发送
        ck=wx.CheckBox(self, -1, u"定时发送(单位ms)");
        ck.Bind(wx.EVT_CHECKBOX, self.OnSendTimely);
        gridSizer.Add(ck, pos=(3, 0), size=(1,1), flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL);

        #定时发送时间
        self.textSendInterval = wx.lib.intctrl.IntCtrl( self, size=( 50, -1 ) )
        gridSizer.Add(self.textSendInterval, pos=(3, 1), size=(1,1), flag=wx.ALIGN_CENTER_VERTICAL);
        self.textSendInterval.Bind(wx.lib.intctrl.EVT_INT, self.SendIntervalSet)

        self.textSendInterval.SetValue(int(Config.APP_CONFIG['module_send']['sendInterval']));


        #发送按钮
        btn = wx.Button(self, -1, u"发送");
        self.Bind(wx.EVT_BUTTON, self.OnSendData, btn);
        gridSizer.Add(btn, pos=(4, 0), size=(1,1), flag=wx.ALIGN_CENTER_VERTICAL);
        
        #清空
        btn = wx.Button(self, -1, u"清空")
        self.Bind(wx.EVT_BUTTON, self.OnClearData, btn);
        gridSizer.Add(btn, pos=(4, 1), size=(1,1), flag=wx.ALIGN_CENTER_VERTICAL);

        gridSizer.AddGrowableCol(2);
        gridSizer.AddGrowableRow(1);


        ############# 结束布局 ###########
        self.SetSizer(gridSizer)
        self.SetAutoLayout(True)
    
    #接收到数据
    def RecvData(self, data):
        pass;
    
    #设置定时发送间隔
    def SendIntervalSet(self, event):
        self.sendTimelyInterval = event.GetEventObject().GetValue();
        Config.APP_CONFIG['module_send']['sendInterval']=str(self.sendTimelyInterval)
        if self.sendTimer.IsRunning():
            self.sendTimer.Stop();
            self.sendTimer.Start(self.sendTimelyInterval);
        
    #定时发送
    def OnSendTimely(self, event):
        
        self.sendTimelyMode = event.GetEventObject().GetValue();
        if self.sendTimelyMode:
            if Global.SerialGeniusPort and Global.SerialGeniusPort.running:
                if self.sendTimelyInterval<=0:
                    wx.MessageBox(u'请设置发送间隔',u'提示');
                    event.GetEventObject().SetValue(False);
                else:
                    self.sendTimer.Start(self.sendTimelyInterval);
            else:
                wx.MessageBox(u'请先打开串口',u'提示');
                event.GetEventObject().SetValue(False);
        else:
            if self.sendTimer.IsRunning():
                self.sendTimer.Stop();
    
    def OnKillFocus(self, event):
        charList=list(self.textSendData.GetValue());
        if self.hexMode:
            validNumberChar=[   ord('0'),ord('1'),ord('2'),ord('3'),ord('4'),ord('5'),ord('6'),ord('7'),ord('8'),
                                ord('9'),ord('a'),ord('b'),ord('c'),ord('d'),ord('e'),ord('f'),ord('A'),ord('B'),ord('C'),
                                ord('D'),ord('E'),ord('F')];
            strHex=[];
            del self.dataHexBuffer[:];
            for i in range(0, len(charList)):
                if ord(charList[i]) in validNumberChar:
                    strHex.append(charList[i]);
                    if len(strHex)==2:
                        self.dataHexBuffer.append(string.atoi(''.join(strHex), 16));
                        del strHex[:];
            
            if len(strHex)==0:
                self.SetSendDataWindow(self.dataHexBuffer);
            else:
                wx.MessageBox(u'十六进制格式不正确');
                self.textSendData.SetFocus();
                
        else:            
            del self.dataBuffer[:];
            for i in range(0,len(charList)):
                self.dataBuffer.append(ord(charList[i]));
    
    #清空数据
    def OnClearData(self, event):
        if self.hexMode:
            del self.dataHexBuffer[:];
            self.SetSendDataWindow(self.dataHexBuffer);
        else:
            del self.dataBuffer[:];
            self.SetSendDataWindow(self.dataBuffer);
    
    #发送数据Timer
    def OnSendDataTimer(self, event):
        if Global.SerialGeniusPort and Global.SerialGeniusPort.running:
            if self.hexMode:
                Global.SerialGeniusPort.SendAppend(self.dataHexBuffer);
            else:
                Global.SerialGeniusPort.SendAppend(self.dataBuffer);
                if self.sendNewLineMode:
                    Global.SerialGeniusPort.SendAppend([0x0D]);
                    Global.SerialGeniusPort.SendAppend([0x0A]);
    
    #发送数据
    def OnSendData(self, event):
        if Global.SerialGeniusPort and Global.SerialGeniusPort.running:
            if self.hexMode:
                Global.SerialGeniusPort.SendAppend(self.dataHexBuffer);
            else:
                Global.SerialGeniusPort.SendAppend(self.dataBuffer);
                if self.sendNewLineMode:
                    Global.SerialGeniusPort.SendAppend([0x0D]);
                    Global.SerialGeniusPort.SendAppend([0x0A]);
        else:
            wx.MessageBox(u'请先打开串口',u'提示');
    
    #设置十六进制显示模式
    def OnHexMode(self, event):
        Loading.Show();
        self.hexMode = event.GetEventObject().GetValue();
        if self.hexMode:            
            self.SetSendDataWindow(self.dataHexBuffer);
            self.checkboxNewLine.Enable(False);
            Config.APP_CONFIG['module_send']['hexMode']='1';
        else:
            self.SetSendDataWindow(self.dataBuffer);
            self.checkboxNewLine.Enable(True);
            Config.APP_CONFIG['module_send']['hexMode']='0';
        Loading.Hide();
        
        

    #选择发送文件
    def OnSelectFile(self, event):
        dlg = wx.FileDialog(
            self, message=u"请选择需要发送的文件",
            defaultDir=os.getcwd(), 
            defaultFile="",
            wildcard="All files (*.*)|*.*",
            style=wx.OPEN | wx.CHANGE_DIR
            )
        if dlg.ShowModal() == wx.ID_OK:
            Loading.Show();
            try:
                path=dlg.GetPaths();
                f=open(''.join(path),'rb');       
                del self.dataHexBuffer[:];
                charList=list(f.read(-1));
                
                for i in range(0, len(charList)):
                    self.dataHexBuffer.append(ord(charList[i]));

                self.checkboxHexMode.SetValue(True);
                self.hexMode=True;
                self.SetSendDataWindow(self.dataHexBuffer);
                Loading.Hide();
            except:
                Loading.Hide();
                ELog.Trace();
        dlg.Destroy()
    
    #设置新行发送模式
    def OnSendNewLineMode(self, event):
        self.sendNewLineMode = event.GetEventObject().GetValue();        
        if self.sendNewLineMode:
            Config.APP_CONFIG['module_send']['sendNewLine']='1';
        else:
            Config.APP_CONFIG['module_send']['sendNewLine']='0';

    #设置发送内容
    def SetSendDataWindow(self, data):
        dataStr=[];
        length=len(data);
        #print length;
        if self.hexMode:
            for i in range(0, length):
                dataStr.append('%02X ' % data[i]);
        else:
            for i in range(0, length):
                if data[i]>=0x80:
                    dataStr.append('?');
                else:
                    dataStr.append(chr(data[i]));
        self.textSendData.WriteText(''.join(dataStr));
        self.textSendData.SetValue(''.join(dataStr));
        
          